import { Component, EventEmitter, Injector, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
import { forEach as _forEach, remove as _remove } from 'lodash-es';
import { DateTime } from 'luxon';
import {
    FileObjectConfigDto,
    FileUploadServiceProxy,
    InternalSingleUploadMergeInput,
    InternalSingleUploadVerifyInput,
    MultipartUploadServiceProxy
} from "@shared/service-proxies/service-proxies";
import { AppConsts } from '@shared/AppConsts';
import { finalize } from 'rxjs/operators';
import { TokenService, MessageService } from 'abp-ng2-module';
import { FileUploadHelper } from '@shared/helpers/FileUploadHelper';
import { AppLocalizationService } from '../localization/app-localization.service';
import { DomSanitizer } from '@angular/platform-browser';
import { AppNotifyService } from '@shared/utils/service/app-notify.service';
import { FindingFileItem } from '../file-finder/file-finder-options';
import { MultipartUploadHelper } from '../multipart-upload/multipart-upload-helper';
import { Status } from '../multipart-upload/multipart-upload-option';

@Component({
    selector: 'single-upload2',
    templateUrl: './single-upload2.component.html'
})
export class SingleUpload2Component implements OnInit, OnChanges {

    @Input() picurl: string;
    @Output() picurlChange = new EventEmitter<string>();

    @Input() customKey: string;
    @Input() defaultKey: string;

    @Input() description: string;

    @Input() label: string;

    @Input() canEdit: boolean = false;

    @Input() uploadType: number;  //目的是为了可以直接使用是batchUpload 中的某个配置（旧版栏目信息是这样配置的）
    @Input() alias: string;

    config: FileObjectConfigDto;

    private exName: string;
    icon: string;
    remoteUrl: string;
    remoteSmallUrl: string;

    private _multipartUploadHelper: MultipartUploadHelper;

    get showProgressBar(){
        return this._multipartUploadHelper.showHashProgress || this._multipartUploadHelper.showMerging
         || [Status.pause, Status.uploading, Status.error].includes(this._multipartUploadHelper.status);
    }

    get uploadProgress(): number {
		return this._multipartUploadHelper.uploadProgress;
	}

    constructor(
        private _fileUploadServiceProxy: FileUploadServiceProxy,
        private _tokenService: TokenService,
        private message: MessageService,
        private notify: AppNotifyService,
        protected dom: DomSanitizer,
        private _appLocalizationService: AppLocalizationService,
        private _multipartUploadService: MultipartUploadServiceProxy
    ) {
        this.config = new FileObjectConfigDto();

        this._multipartUploadHelper = new MultipartUploadHelper(notify, _tokenService);
    }

    ngOnChanges(changes: SimpleChanges): void {
        if (changes['picurl']) {
            this.updateData();
        }

        if (changes['description']){
            this.config.description = this._appLocalizationService.l(this.description);
        }
    }

    ngOnInit(): void {
        if (!this.label) {
            this.label = this._appLocalizationService.l("Picture");
        }

        this.InitializeUpload();

        if (this.customKey) {
            if (!this.defaultKey) {
                this.defaultKey = '';
            }
            this._fileUploadServiceProxy.getSingleConfigInfo(this.alias, this.customKey)
                .subscribe(result => {
                    this.config = result;

                    if (this.description) {
                        this.config.description =  this._appLocalizationService.l(this.description);
                    }
                });

        } 
    }
    
    private InitializeUpload() {
        this._multipartUploadHelper.Initialize(4, {
            uploaderUrl: AppConsts.remoteServiceBaseUrl + '/B/FileUpload/FileUploadDealTwo',
            partUploaderUrl: AppConsts.remoteServiceBaseUrl + '/B/EditorFile/PartUpload',
            singleUploaderOnBuildItemForm: (fileItem, form) => {
                form.append('customKey', this.customKey);
                form.append('alias', this.alias);
            },
            uploadedCallback: (fileItem) => {
                this.picurl = fileItem.imgUrl;
                this.picurlChange.emit(this.picurl);
                this.updateData();
            },
            verifyFunction: (t) => {
                return this._multipartUploadService.internalSingleUploadVerify(t);
            },
            getVerifyInput: (fileContainer) => {
                return new InternalSingleUploadVerifyInput({
                    fileHash: fileContainer.hash,
                    fileName: fileContainer.file.name,
                    customKey: this.customKey,
                    alias: this.alias
                });
            },
            getMergeRequestInput: () => {
                return new InternalSingleUploadMergeInput({
                    fileHash: this._multipartUploadHelper.container.hash,
                    fileName: this._multipartUploadHelper.container.file.name,
                    fileSize: this._multipartUploadHelper.container.file.size,
                    dimensions: this._multipartUploadHelper.container.dimensions,
                    count: this._multipartUploadHelper.chunks.length,
                    customKey: this.customKey,
                    alias: this.alias
                });
            },
            mergeRequestFunction: (t) => {
                return this._multipartUploadService.internalSingleUploadMerge(t);
            }
        });
    }

    checkPic(event: any) {
        if (!this.canEdit || this._multipartUploadHelper.status === Status.uploading) {
            event.target.value = null;
            return;
        }

        if (event.target.files && event.target.files.length > 0) {
            let file = event.target.files[0];
            
            event.target.value = null;
            if (!FileUploadHelper.check(file.name, this.config.exNames, file.size, 
                this.config.maxSize, this.notify, this._appLocalizationService)) {

                let item = this._multipartUploadHelper.getUploadingFileItem(file);
                this._multipartUploadHelper.uploadingFileQueue.push(item);
                this._multipartUploadHelper.handleUpload();
            }
        }
    };

    private getUrl() {
        return FileUploadHelper.getUrl(this.picurl);
    }

    private getSmallUrl() {
        return FileUploadHelper.getSmallUrl(this.picurl, 250, 60);
    }
    
    lookOver(picurl:string) {
        abp.event.trigger(AppConsts.EventName.showImageView, picurl);
    }

    private updateData(){
        this.exName = FileUploadHelper.getExName(this.picurl);
        this.icon = FileUploadHelper.getIcon(this.exName);
        this.remoteSmallUrl = this.getSmallUrl();
        this.remoteUrl = this.getUrl();
    }

    openPage() {
        let url = FileUploadHelper.getDownUrl(this.exName, this.picurl)
        window.open(url);
        return false;
    };
    delete = function () {
        this.picurl = null;
        this.picurlChange.emit(this.picurl);
        this.updateData();
    };

    pickupFile(){
        abp.event.trigger('abp.ckeditor.filefinder', { editor:null, multiSelect: false, callback: (list: FindingFileItem[])=>{
            if(list.length > 0){
                let item = list[0];
                let fileUrl = item.fileUrl;
                let fileName = item.fileName;
                if (!FileUploadHelper.checkExName(fileName, this.config.exNames)) {
                    let exNameArr = this.config.exNames.split('|');
                    this.notify.error(fileName + '：' + this._appLocalizationService.l('File_Invalid_Type_Error', exNameArr.join('、')));
                    return;
                }

                this.picurl = fileUrl;
                this.picurlChange.emit(this.picurl);
                this.updateData();
            }
        } });
    }
}
